package com.msite.util.encrypt
import sun.misc.BASE64Decoder
import sun.misc.BASE64Encoder

import javax.crypto.KeyGenerator
import javax.crypto.Mac
import javax.crypto.SecretKey
import javax.crypto.spec.SecretKeySpec
import java.security.NoSuchAlgorithmException
/**
 * Created by tpeng on 2015/11/27.
 */
class HMAC {

    /**
     * 定义加密方式
     * MAC算法可选以下多种算法
     * HmacMD5
     * HmacSHA1
     * HmacSHA256
     * HmacSHA384
     * HmacSHA512
     */
    private final static String KEY_MAC = "HmacSHA256";

    private final static String[] hexDigits = [ "0", "1", "2", "3", "4", "5",
        "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" ];

    /**
     * 提供HMAC密钥
     * @return
     */
    public static String initKey() {
        SecretKey key;
        String str = "";
        try {
            KeyGenerator generator = KeyGenerator.getInstance(KEY_MAC);
            key = generator.generateKey();
            str = encryptBase64(key.getEncoded());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * HMAC加密
     * @param data 需要加密的字节数组
     * @param key 密钥
     */
    public static String encryptHMAC(String key, String data) {
        SecretKey secretKey;
        byte[] bytes = null;
        try {
            secretKey = new SecretKeySpec(decryptBase64(key), KEY_MAC);
            Mac mac = Mac.getInstance(secretKey.getAlgorithm());
            mac.init(secretKey);
            bytes = mac.doFinal(data.bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return byteArrayToHexString(bytes);  ;
    }

    /**
     * BASE64 加密
     * @param key 需要加密的字节数组
     * @return 字符串
     * @throws Exception
     */
    public static String encryptBase64(byte[] key) throws Exception {
        return (new BASE64Encoder()).encodeBuffer(key);
    }

    /**
     * BASE64 解密
     * @param key 需要解密的字符串
     * @return 字节数组
     * @throws Exception
     */
    public static byte[] decryptBase64(String key) throws Exception {
        return (new BASE64Decoder()).decodeBuffer(key);
    }

    /**
     * 将一个字节转化成十六进制形式的字符串
     * @param b 字节数组
     * @return 字符串
     */
    private static String byteToHexString(byte b) {
        int ret = b;
        if (ret < 0) {
            ret += 256;
        }
        int m = ret / 16;
        int n = ret % 16;
        return hexDigits[m] + hexDigits[n];
    }

    /**
     * 转换字节数组为十六进制字符串
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    private static String byteArrayToHexString(byte[] bytes) {
        def sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            sb.append(byteToHexString(bytes[i]));
        }
        sb.toString();
    }

    public static void main(String[] args) {
        String key = HMAC.initKey();
        System.out.println("Mac密钥:\n" + key);
        String word = "111111";
        println key.length()
        println "---------"
        def res = encryptHMAC(word, "goKaxhgWfINOZgnUVT+MTIoUOYeWVxVucu4RhgjH810=");
        System.out.println(res);
        print res.length()
    }

    //60991cef73f6f17c711a0b801bf7b6bbc15f10e2acacc76272c52675af9658d7
}
